﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Commons.IO
{
	public sealed class BufferingDataSource<T> : IDataSource<T[]>
	{
		IDataSource<T> m_source;
		static int s_buffersize = 16;

		static BufferingDataSource()
		{
			if (typeof(T) == typeof(byte))
				s_buffersize = 1024;
		}

		public BufferingDataSource(IDataSource<T> source)
		{
			this.m_source = source;
		}

		public void Close()
		{
			m_source.Close();
		}

		public void Dispose()
		{
			m_source.Dispose();
		}

		public async Task<T[]> PullAsync(System.Threading.CancellationToken token, IProgress<ProgressEventArgs> progress)
		{
			List<T> list = new List<T>();
			for (int i = 0; i < s_buffersize; i++)
			{
				token.ThrowIfCancellationRequested();
				Task<T> pull = m_source.PullAsync(token, progress);
				if (Task.WhenAny(pull, Task.Delay(0)) == (Task)pull)
					list.Add(await pull);
			}
			return list.ToArray();
		}
	}
}
